/**
 * select_template.mjs
 * 这是一个用于创建和配置下拉选择框的模块
 * 支持本地数据和AJAX远程数据两种模式
 * 提供了丰富的配置选项和数据绑定功能
 */

import render_helper from "./render_helper.mjs";
import render_content from "./render_content.mjs";
import ajax from "./thin_ajax.mjs";
import datarover from "./datarover.mjs";
import {
  nearest_data,
  nearest_datacontainer,
  nearest_param,
} from "./nearest.mjs";
import { thin } from "../thin3.mjs";
import { after, clearafterqueue } from "./delay_render.mjs";

// 主函数：创建和配置select下拉框
export default function (container, template) {
  // 调试模式下打印容器和模板信息
  if (template.debug) {
    console.log({ container, template });
  }

  // 创建select元素并设置基本属性
  let select = document.createElement("select");
  select.name = template.select;
  select.id = template.select;
  // if (template.multiple) select.multiple = true;
  container.appendChild(select);

  let required;

  if (template.required === false) {
    required = {};
  } else if (container.closest("formview")?.thin_allrequired === true) {
    required = { required: true };
  }

  template.a = { ...template.a, ...required };

  // 应用渲染助手处理基础属性
  render_helper(select, template);

  // AJAX模式：从远程获取选项数据
  if (template.ajax) {
    // 监听模式：观察其他元素变化并触发重新渲染
    if (template.ajax.watch) {
      let data_container = nearest_datacontainer(select);
      let watched = data_container.querySelector(template.ajax.watch);
      watched.addEventListener("change", (e) => {
        // 使用延迟渲染队列处理更新
        after(renderoptions);
        setTimeout(clearafterqueue, 20);
      });
    }

    // 渲染AJAX选项的函数
    function renderoptions() {
      let query = {};
      // 处理查询参数
      for (let item in template.ajax.query) {
        if (typeof template.ajax.query[item] === "string") {
          query[item] = render_content(select, template.ajax.query[item]);
        }
      }

      // 发送AJAX请求获取数据
      ajax({
        url: template.ajax.url,
        type: template.ajax.method || "post",
        contentType: "application/JSON",
        data: query,
        success: ajax_render,
      });
    }

    renderoptions();
  } else {
    // 非AJAX模式：直接渲染本地选项
    render();
  }

  // AJAX数据渲染处理函数
  function ajax_render(data) {
    thin(select).empty();
    select.options.add(new Option(""));
    let opt = datarover(data, template.ajax.datapath);

    if (Array.isArray(opt)) {
      opt.forEach((op) => {
        // 处理选项的值：支持模板语法[[xxx]]或直接取值
        let value = /\[\[[\w/.]+\]\]/.test(template.ajax.value)
          ? render_content(op, template.ajax.value)
          : datarover(op, template.ajax.value);
        // 处理选项的显示文本
        let text = render_content(
          op,
          template.ajax.text || template.ajax.value
        );

        let opt = new Option(text, value);
        opt.thin_data = op; // 在选项上存储原始数据，供后续使用
        select.options.add(opt);
      });
    }

    // 设置选中值
    if (template.bind) select.value = datarover(select, template.bind);
    if (template.value) select.value = render_content(select, template.value);

    // 绑定选择事件处理
    if (template.ajax.onselect) {
      select.addEventListener("change", (e) => {
        template.ajax.onselect({
          select: select.selectedOptions[0].thin_data,
          data: nearest_data(select),
        });
      });
    }
  }

  // 本地数据渲染函数
  function render() {
    if (template.options) {
      // 处理watch配置：监听其他元素变化
      if (template.watch) {
        let ele = document.querySelector(template.watch);
        ele?.addEventListener("change", (e) => {
          // TODO: 实现监听变化后的处理逻辑
        });
      } else render_options();

      // 渲染本地选项的具体实现
      function render_options() {
        // 1. 处理字符串类型的options：通过数据路径获取选项
        if (typeof template.options === "string") {
          let opt = datarover(select, template.options);
          if (Array.isArray(opt)) {
            opt.unshift(""); // 添加空选项
            opt.forEach((op) => {
              // 处理简单值和对象类型的选项
              if (!["object", "array"].includes(typeof op))
                select.options.add(new Option(op));
              else if (typeof op === "object")
                select.options.add(new Option(op.text, op.value));
            });
          }
        }
        // 2. 处理函数类型的options：调用函数获取选项
        else if (typeof template.options === "function") {
          template
            .options({
              container: select,
              data: nearest_data(container),
              param: nearest_param(container),
            })
            ?.forEach((op) => {
              select.options.add(new Option(op));
            });
        }
        // 3. 处理数组类型的options：直接遍历数组
        else if (Array.isArray(template.options)) {
          template.options.forEach((op) => {
            if (template.text) {
              // 支持自定义文本和值的渲染
              select.options.add(
                new Option(
                  render_content(op, template.text || template.value),
                  render_content(op, template.value || template.text)
                )
              );
            } else {
              // 直接使用数组项作为选项
              select.options.add(new Option(op));
            }
          });
        }
        // 4. 处理对象类型的options：支持data数组或键值对形式
        else if (typeof template.options === "object") {
          if (Array.isArray(template.options.data)) {
            // 处理data数组形式
            template.options.data.forEach((row) => {
              let opt = new Option(
                render_content(
                  row,
                  template.options.text || template.options.value
                ),
                render_content(row, template.options.value)
              );
              select.options.add(opt);
            });
          } else {
            // 处理键值对形式
            for (let op in template.options) {
              select.options.add(new Option(template.options[op], op));
            }
          }
        }
      }
    }

    // 设置选中值：支持数据绑定和直接赋值两种方式
    if (template.bind) select.value = datarover(select, template.bind);
    if (template.value) select.value = render_content(select, template.value);
  }
}
